package com.ruoyi.crm.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.crm.domain.AssignRecord;
import com.ruoyi.crm.domain.Business;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.crm.mapper.ClueMapper;
import com.ruoyi.crm.domain.Clue;
import com.ruoyi.crm.service.IClueService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 线索Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-16
 */
@Service
public class ClueServiceImpl implements IClueService {
    @Resource
    private ClueMapper clueMapper;

    @Resource
    private KieContainer kieContainer;

    @Resource
    private AssignRecordServiceImpl assignRecordService;

    @Resource
    private BusinessServiceImpl businessService;

    /**
     * 查询线索
     *
     * @param id 线索主键
     * @return 线索
     */
    @Override
    public Clue selectClueById(Long id) {
        return clueMapper.selectClueById(id);
    }

    /**
     * 查询线索列表
     *
     * @param clue 线索
     * @return 线索
     */
    @Override
    public List<Clue> selectClueList(Clue clue) {
        return clueMapper.selectClueList(clue);
    }

    /**
     * 新增线索
     *
     * @param clue 线索
     * @return 结果
     */
    @Override
    public int insertClue(Clue clue) {
        clue.setCreateBy(SecurityUtils.getUsername());
        clue.setCreateTime(DateUtils.getNowDate());
        return clueMapper.insertClue(clue);
    }

    /**
     * 修改线索
     *
     * @param clue 线索
     * @return 结果
     */
    @Override
    public int updateClue(Clue clue) {
        // 增加伪线索失败次数(最大数3次)
        clue.setFalseCount(clue.getFalseCount() + 1);
        clue.setUpdateBy(SecurityUtils.getUsername());
        clue.setUpdateTime(DateUtils.getNowDate());
        return clueMapper.updateClue(clue);
    }

    /**
     * 批量删除线索
     *
     * @param ids 需要删除的线索主键
     * @return 结果
     */
    @Override
    public int deleteClueByIds(Long[] ids) {
        return clueMapper.deleteClueByIds(ids);
    }

    /**
     * 删除线索信息
     *
     * @param id 线索主键
     * @return 结果
     */
    @Override
    public int deleteClueById(Long id) {
        return clueMapper.deleteClueById(id);
    }

    //    批量添加线索
    @Override
    @Transactional
    public int uploadClues(List<Clue> clues) {
        int sum = 0;
        KieSession kieSession = kieContainer.newKieSession();
        for (Clue clue : clues) {
//            调用规则引擎，自动分配归属人
            kieSession.insert(clue);
            kieSession.fireAllRules();

//            转换字典表数据
            clue.setChannel((DictUtils.getDictValue("clues_item", clue.getChannel())));     // 渠道来源
            clue.setSex(DictUtils.getDictValue("sys_user_sex", clue.getSex()));             // 用户性别
            clue.setLevel(DictUtils.getDictValue("clues_level", clue.getLevel()));          // 意向级别
            clue.setSubject(DictUtils.getDictValue("course_subject", clue.getSubject()));   // 意向学科
            clue.setStatus(Clue.Status.NEW.getValue());                                             // 状态
            sum += this.insertClue(clue);

//            分配线索给指定用户
            AssignRecord assignRecord = new AssignRecord();
            assignRecord.setType(AssignRecord.Type.CLUE.name());
            assignRecord.setAssignId(clue.getId());
            assignRecord.setCreateTime(new Date());
            setUserInfo(assignRecord, clue.getOwner());
            assignRecordService.insertAssignRecord(assignRecord);
        }
        kieSession.destroy();
        return sum;
    }

    private void setUserInfo(AssignRecord assignRecord, String owner) {
        Map<String, Object> userInfo = getUserInfo(owner);
        assignRecord.setUserId((Long) userInfo.get("user_id"));
        assignRecord.setUserId((Long) userInfo.get("dept_id"));
        assignRecord.setUserName(owner);
    }

    /**
     * 根据用户名获取id和dept_id，手动缓存查询
     */
    public Map<String, Object> getUserInfo(String userName) {
        final String key = "crm:clue:userInfo:" + userName;
        RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
        Map<String, Object> cacheMap = redisCache.getCacheMap(key);
        if (cacheMap.isEmpty()) {
            cacheMap = clueMapper.selectUserInfo(userName);
            redisCache.setCacheMap(key, cacheMap);
            redisCache.expire(key, 5, TimeUnit.MINUTES);
        }
        return cacheMap;
    }

    /**
     * 伪线索上报
     * 1、falseCount最大值为3
     * 2、状态改为 伪线索
     *
     * @param id
     * @return
     */
    @Override
    public int falseClue(Long id) {
        Clue clue = this.selectClueById(id);
        if (clue.getFalseCount() >= Clue.FALSE_COUNT_LIMIT) {
            throw new RuntimeException("伪线索次数超限！");
        }
        clue.setStatus(Clue.Status.FALSE.getValue());
        return this.updateClue(clue);
    }

    /**
     * 转商机
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public int transformToBusiness(Long id) {
        // 修改线索状态
        Clue clue = this.selectClueById(id);
        clue.setStatus(Clue.Status.TO_BUSINESS.getValue());
        this.updateClue(clue);
        // 添加商机
        Business business = new Business();
        BeanUtils.copyProperties(clue, business);
        // 线索ID
        business.setClueId(clue.getId());
        business.setStatus(Clue.Status.NEW.getValue());
        return businessService.insertBusiness(business);
    }

    /**
     * 重新捞取线索
     * // 插入分配记录
     *
     * @param id
     * @return
     */
    @Override
    public int resetClue(Long id) {
        // 插入分配记录
        AssignRecord assignRecord = new AssignRecord();
        assignRecord.setType(AssignRecord.Type.CLUE.name());
        assignRecord.setAssignId(id);
        // 归属人(谁捞取的归属人就是谁)
        assignRecord.setUserId(SecurityUtils.getUserId());
        assignRecord.setUserName(SecurityUtils.getUsername());
        return assignRecordService.insertAssignRecord(assignRecord);
    }
}
